package cn.b.sky.form.service.impl;

import cn.b.sky.common.exception.ImeException;
import cn.b.sky.common.utils.DatabaseUtils;
import cn.b.sky.form.dao.ScreenDao;
import cn.b.sky.form.dao.ScreenFieldDao;
import cn.b.sky.form.dao.SectionDao;
import cn.b.sky.form.model.Screen;
import cn.b.sky.form.model.ScreenField;
import cn.b.sky.form.model.Section;
import cn.b.sky.form.model.condition.ScreenCondition;
import cn.b.sky.form.service.ScreenService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import java.util.List;

@Service("screenService")
public class ScreenServiceImpl implements ScreenService {

  private static final Logger LOG = LoggerFactory.getLogger(ScreenServiceImpl.class);

  @Resource
  ScreenDao screenDao;

  @Resource
  SectionDao sectionDao;

  @Resource
  ScreenFieldDao screenFieldDao;

  @Override
  public List<Screen> selectScreenListByCondition(ScreenCondition condition) {
    if (null == condition) {
      return null;
    }
    if (StringUtils.isBlank(condition.getOrderField())) {
      condition.setOrderField("CreateDateTime");
    }
    return screenDao.selectScreenListByCondition(condition);
  }

  @Override
  public int selectScreenListCountByCondition(ScreenCondition condition) {
    if (condition != null) {
      return screenDao.selectScreenListCountByCondition(condition);
    }
    return 0;
  }

  @Override
  public Screen getScreen(String siteCode, String screenCode) {
    if (!StringUtils.isBlank(screenCode)) {
      Screen screen = screenDao.getScreen(siteCode, screenCode);
      if(screen == null || StringUtils.isBlank(screen.getScreenCode())){
        throw ImeException.newException("customForm_notExtis.M", screenCode);
      }
      List<Section> list = sectionDao.selectSectionByscreenCode(siteCode, screenCode);
      for (Section section : list) {
        List<ScreenField> sectionList = screenFieldDao.selectScreenFieldBySectionCode(siteCode,
            screen.getBusinessType(), screenCode, section.getSectionCode());
        section.setScreenField(sectionList);
      }
      screen.setSections(list);
      return screen;
    }
    return null;
  }

  @Override
  public void insertScreen(Screen screen) {
    if (screen != null) {
      screenDao.insertScreen(screen);
      for (Section section : screen.getSections()) {
        section.setSiteCode(screen.getSiteCode());
        section.setScreenCode(screen.getScreenCode());
        sectionDao.insertSection(section);
        for (ScreenField screenField : section.getScreenField()) {
          screenField.setId(null);
          screenField.setSiteCode(screen.getSiteCode());
          screenField.setBusinessType(screen.getBusinessType());
          screenField.setScreenCode(screen.getScreenCode());
          screenField.setSectionCode(section.getSectionCode());
          screenFieldDao.insertScreenField(screenField);
        }
      }
    }
  }

  @Override
  public void updateScreen(Screen screen) {
    if (screen != null) {
      screenDao.updateScreen(screen);
      List<Section> oldSectionList = sectionDao.selectSectionByscreenCode(screen.getSiteCode(), screen.getScreenCode());
      for (Section delSection : oldSectionList) {
        boolean isExist = true;
        for (Section newSection : screen.getSections()) {
          if (delSection.getSectionCode().equals(newSection.getSectionCode())) {
            isExist = false;
            break;
          }
        }
        if (isExist) {
          screenFieldDao.deleteScreenFieldBySection(screen.getSiteCode(), screen.getBusinessType(),
              screen.getScreenCode(), delSection.getSectionCode());
          sectionDao.deleteSectionByScreenCode(delSection.getSiteCode(), delSection.getScreenCode(),
              delSection.getSectionCode());
        }
      }
      for (Section section : screen.getSections()) {
        Section oldSection = sectionDao.getSectionBySectionCode(screen.getSiteCode(), screen.getScreenCode(),
            section.getSectionCode());
        if (oldSection != null) {
          section.setSiteCode(screen.getSiteCode());
          section.setScreenCode(screen.getScreenCode());
          sectionDao.updateSection(section);
          List<ScreenField> oldScreenFieldList = screenFieldDao.selectScreenFieldBySectionCode(screen.getSiteCode(),
              screen.getBusinessType(), screen.getScreenCode(), section.getSectionCode());
          for (ScreenField oldScreenField : oldScreenFieldList) {
            boolean isExist = false;
            for (ScreenField updateScreenField : section.getScreenField()) {
              if (oldScreenField.getId().equals(updateScreenField.getId())) {
                isExist = true;                    
              }
              if (isExist) {
                break;
              }
            }
            if (isExist == false) {
              screenFieldDao.deleteScreenFieldByID(oldScreenField.getId());
            }
          }
          for (ScreenField screenField : section.getScreenField()) {
            if (screenField.getId()==null) {
              screenField.setSiteCode(screen.getSiteCode());
              screenField.setBusinessType(screen.getBusinessType());
              screenField.setScreenCode(screen.getScreenCode());
              screenField.setSectionCode(section.getSectionCode());
              screenFieldDao.insertScreenField(screenField);
            } else {
              screenFieldDao.updateScreenFieldByID(screenField);
            }
          }
        }else {
          section.setSiteCode(screen.getSiteCode());
          section.setScreenCode(screen.getScreenCode());
          sectionDao.insertSection(section);
          for (ScreenField screenField : section.getScreenField()) {
            screenField.setSiteCode(screen.getSiteCode());
            screenField.setBusinessType(screen.getBusinessType());
            screenField.setScreenCode(screen.getScreenCode());
            screenField.setSectionCode(section.getSectionCode());
            screenFieldDao.insertScreenField(screenField);
          }
        }
      }
    }
  }

  @Override
  public String deleteScreen(String siteCode, String screenCode) {
    String message = null;
    try {
      Screen screen = screenDao.getScreen(siteCode, screenCode);
      List<Section> sections = sectionDao.selectSectionByscreenCode(siteCode, screenCode);
      for (Section section : sections) {
        screenFieldDao.deleteScreenFieldBySection(section.getSiteCode(), screen.getBusinessType(),
            screen.getScreenCode(), section.getSectionCode());
        sectionDao.deleteSectionByScreenCode(section.getSiteCode(), section.getScreenCode(),
            section.getSectionCode());
      }
      screenDao.deleteScreen(siteCode, screenCode);
    } catch (Exception e) {
      LOG.error("{}", e);
      TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
      if ((DatabaseUtils.isConstraintsError(e.getMessage()))) {
        message = "dataBaseOperationPkFail.M";
      }
    }
    return message;
    
  }

  @Override
  public Screen validateScreen(String siteCode, String screenCode) {
    if (!StringUtils.isBlank(screenCode)) {
      return screenDao.getScreen(siteCode, screenCode);
    }
    return null;
  }

  @Override
  public List<Section> selectSectionByScreen(String siteCode, String businessType, String screenCode) {
    if (!StringUtils.isBlank(screenCode) && !StringUtils.isBlank(siteCode)) {
      List<Section> sectionList = sectionDao.selectSectionByscreenCode(siteCode, screenCode);
      for (Section section : sectionList) {
        List<ScreenField> screenFieldList = screenFieldDao.selectScreenFieldBySectionCode(siteCode, businessType,
            screenCode, section.getSectionCode());
        section.setScreenField(screenFieldList);
      }
      return sectionList;
    }
    return null;
  }

  @Override
  public void saveAsSection(String siteCode,String oldScreenCode, Screen screen) {
    Screen oldScreen = screenDao.getScreen(siteCode, oldScreenCode);
    screen.setSiteCode(siteCode);
    screen.setBusinessType(oldScreen.getBusinessType());
    List<Section> sections = this.selectSectionByScreen(siteCode, screen.getBusinessType(), oldScreenCode);
    screen.setSections(sections);
    this.insertScreen(screen);
  }

  @Override
  public List<Screen> selectScreenSuggestByCondition(ScreenCondition condition) {
    
    return screenDao.selectScreenSuggestByCondition(condition);
  }

  @Override
  public String getScreenText(String siteCode, String screenCode) {
    Screen screen = screenDao.getScreen(siteCode, screenCode);
    return screen != null ? screen.getScreenText() : null;
  }

}
